package org.amphiprion.diceroller.dao;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.amphiprion.diceroller.ApplicationConstants;
import org.amphiprion.diceroller.entity.Game;
import org.amphiprion.diceroller.entity.GameDice;
import org.amphiprion.diceroller.entity.GameDiceFace;
import org.amphiprion.diceroller.entity.GameDiceFaceSymbole;
import org.amphiprion.diceroller.entity.GameSymbole;
import org.amphiprion.diceroller.util.PreferenceUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.util.Log;

public class GameDao extends AbstractXmlDao {
	private static GameDao instance;

	public static GameDao getInstance() {
		if (instance == null) {
			instance = new GameDao();
		}
		return instance;
	}

	public Game getGame(String filename) {
		InputStream is = null;
		try {
			String lng = PreferenceUtil.getLanguage();
			Game game = new Game();

			File f = new File(filename);

			if (f.exists()) {
				is = new FileInputStream(f);
			}
			if (is == null) {
				throw new RuntimeException("File " + f.getAbsolutePath() + " does not exist!");
			}

			DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
			builderFactory.setNamespaceAware(true);

			DocumentBuilder builder = builderFactory.newDocumentBuilder();
			Document document = builder.parse(is);

			NodeList list = document.getElementsByTagName("game");
			Element gameNode = (Element) list.item(0);
			// String id = getAttribute(gameNode, "id", "");
			// game.setId(id);
			game.setBackground(getAttribute(gameNode, "background", null));
			game.setDiceChooserBackgroundImage(getAttribute(gameNode, "diceChooserBackgroundImage", null));
			game.setDiceChooserLeftImage(getAttribute(gameNode, "diceChooserLeftImage", null));
			game.setDiceChooserRightImage(getAttribute(gameNode, "diceChooserRightImage", null));

			// game.setName(getLocalizedText(gameNode, lng));

			// Game Symboles
			list = ((Element) (document.getElementsByTagName("symboles")).item(0)).getElementsByTagName("symbole");
			for (int i = 0; i < list.getLength(); i++) {
				Element symboleNode = (Element) list.item(i);
				GameSymbole symb = new GameSymbole();
				symb.setId(getAttribute(symboleNode, "id", ""));
				symb.setImage(getAttribute(symboleNode, "image", ""));

				game.getGameSymboles().put(symb.getId(), symb);

				NodeList listReplace = symboleNode.getElementsByTagName("replace");
				for (int j = 0; j < listReplace.getLength(); j++) {
					Element replaceNode = (Element) listReplace.item(j);

					symb.setReplaceValue(getFloatAttribute(replaceNode, "value", 0), getFloatAttribute(replaceNode, "by", 0));
				}

			}

			// Dices
			collectDices(game, gameNode);

			is.close();

			return game;
		} catch (Throwable e) {
			Log.e(ApplicationConstants.PACKAGE, "", e);
			if (is != null) {
				try {
					is.close();
				} catch (Throwable ex) {
				}
			}
			return null;
		}
	}

	private void collectDices(Game game, Element gameNode) {
		NodeList list = ((Element) (gameNode.getElementsByTagName("dices")).item(0)).getElementsByTagName("dice");
		for (int i = 0; i < list.getLength(); i++) {
			Element diceNode = (Element) list.item(i);
			GameDice gameDice = new GameDice();
			gameDice.setId(getAttribute(diceNode, "id", ""));
			gameDice.setType(getAttribute(diceNode, "type", ""));
			gameDice.setViewName(getAttribute(diceNode, "view", ""));
			gameDice.setUvTextureName(getAttribute(diceNode, "UVtexture", ""));
			game.getGameDices().add(gameDice);

			collectDiceFaces(game, gameDice, diceNode);

		}

	}

	private void collectDiceFaces(Game game, GameDice gameDice, Element diceNode) {
		NodeList list = diceNode.getElementsByTagName("face");
		for (int i = 0; i < list.getLength(); i++) {
			Element faceNode = (Element) list.item(i);
			GameDiceFace gameDiceFace = new GameDiceFace();
			gameDiceFace.setNumber(getAttribute(faceNode, "num", ""));

			gameDice.getDiceFaces().put(gameDiceFace.getNumber(), gameDiceFace);
			collectGameDiceFaceSymbole(game, gameDiceFace, faceNode);
		}

	}

	private void collectGameDiceFaceSymbole(Game game, GameDiceFace gameDiceFace, Element faceNode) {
		NodeList list = faceNode.getElementsByTagName("symbole-ref");
		for (int i = 0; i < list.getLength(); i++) {
			Element symboleRefNode = (Element) list.item(i);
			GameDiceFaceSymbole gameDiceFaceSymbole = new GameDiceFaceSymbole();
			gameDiceFaceSymbole.setSymbole(game.getGameSymboles().get(getAttribute(symboleRefNode, "ref-id", "")));
			gameDiceFaceSymbole.setValue(getFloatAttribute(symboleRefNode, "value", 1));
			gameDiceFace.getFaceSymboles().add(gameDiceFaceSymbole);
		}

	}

}
